
from vnpy.trader.object import PositionData
from pandas.core.frame import DataFrame
import re
import glob
from vnpy.app.cta_strategy import (
    CtaTemplate,
    StopOrder,
    TickData,
    BarData,
    TradeData,
    OrderData,
    BarGenerator,
    ArrayManager,
)
from .dw_client import *
from vnpy.trader.constant import (
    Direction,
    Offset,
    Status
)
import pytz
from typing import List, Optional,Dict
import multiprocessing
from vnpy.trader.constant import (
    Direction,
    Offset,
    OrderType,
    Exchange
)
import threading
import time
import os

from vnpy_ctp.gateway.ctp_gateway import DIRECTION_VT2CTP, OFFSET_CTP2VT
from .time_factor import create_time_factor
from .factor import create_factor
import pandas as pd
import numpy as np
from queue import Queue
from datetime import date, datetime,time, timedelta, tzinfo
import pickle
from collections import deque
# from .sqlite_db import db,update_database_orderdata,get_database_orderdata,OrderTable

EXCHANGE_CTP2VT_ST: Dict[str, Exchange] = {
    "CFFEX": Exchange.CFFEX,
    "SHFE": Exchange.SHFE,
    "CZCE": Exchange.CZCE,
    "DCE": Exchange.DCE,
    "INE": Exchange.INE
}

LIMIT_CTP2VT_ST:Dict[str,OrderType]={
    "限价":OrderType.LIMIT,
    "市价":OrderType.MARKET,
    "STOP":OrderType.STOP,   
    "FAK":OrderType.FAK,   
    "FOK":OrderType.FOK,   
    "询价":OrderType.RFQ
}    
DIRECTION_CTP2VT_ST:Dict[str,Direction]={
    "多":Direction.LONG,
    "空":Direction.SHORT,
    "净":Direction.NET
}




OFFSET_CTP2VT_ST:Dict[str,Offset]={
    "":Offset.NONE, 
    "开":Offset.OPEN ,
    "平":Offset.CLOSE,
    "平今":Offset.CLOSETODAY,
    "平昨":Offset.CLOSEYESTERDAY
}
STATUS_CTP2VT_ST={
    "提交中":Status.SUBMITTING,
    "未成交":Status.NOTTRADED,
    "部分成交":Status.PARTTRADED,
    "全部成交":Status.ALLTRADED,
    "已撤销":Status.CANCELLED,
    "拒单":Status.REJECTED
}
from peewee import CharField, DateField, IntegerField,  SqliteDatabase,Model,FloatField
# db=SqliteDatabase('/root/.vntrader/order_database.db')
# class OrderTable(Model):
#     gateway_name=CharField()
#     symbol=CharField()
#     exchange=CharField()
#     orderid=CharField()
#     ordersysid=CharField()
#     type=CharField()

#     direction=CharField()
#     offset=CharField()
#     price=CharField()

#     volume=FloatField()
#     traded=FloatField()
#     status=CharField()
#     datetime=DateField()
#     reference=CharField()
#     #直接存最后一个Order即可，把OrderID直接全部复刻过来，每次启动先去上面找东西，找不到就推一个初始化的数据，signal=0的时候有一组特定的输入
    
    
#     class Meta:
#         database=db
#         indexes=(
#             (('symbol',),True),
#         )
BROKER_ID=""
def send_wechat(text:str):
    requests.get(url="http://192.168.1.68:8383/sendMessageDeepWin/Deepwin@123/7/" + text)
# def get_database_orderdata(symbol:str)->OrderData:
#     # return order
#     pass

# def update_database_orderdata(order:OrderData):
#     pass
    
    

future_code_dict = {'A':'A9999.XDCE', 'AG':'AG9999.XSGE', 'AL':'AL9999.XSGE', 'AU':'AU9999.XSGE',
                        'B':'B9999.XDCE', 'BB':'BB9999.XDCE', 'BU':'BU9999.XSGE', 'C':'C9999.XDCE', 
                        'CF':'CF9999.XZCE', 'CS':'CS9999.XDCE', 'CU':'CU9999.XSGE', 'ER':'ER9999.XZCE', 
                        'FB':'FB9999.XDCE', 'FG':'FG9999.XZCE', 'FU':'FU9999.XSGE', 'GN':'GN9999.XZCE', 
                        'HC':'HC9999.XSGE', 'I':'I9999.XDCE', 
                        'IC':'IC9999.CCFX', 'IF':'IF9999.CCFX', 'IH':'IH9999.CCFX', 
                        'J':'J9999.XDCE', 'JD':'JD9999.XDCE', 'JM':'JM9999.XDCE', 
                        'JR':'JR9999.XZCE', 'L':'L9999.XDCE', 'LR':'LR9999.XZCE', 'M':'M9999.XDCE', 
                        'MA':'MA9999.XZCE', 'ME':'ME9999.XZCE', 'NI':'NI9999.XSGE', 'OI':'OI9999.XZCE', 
                        'P':'P9999.XDCE', 'PB':'PB9999.XSGE', 'PM':'PM9999.XZCE', 'PP':'PP9999.XDCE', 
                        'RB':'RB9999.XSGE', 'RI':'RI9999.XZCE', 'RM':'RM9999.XZCE', 'RO':'RO9999.XZCE', 
                        'RS':'RS9999.XZCE', 'RU':'RU9999.XSGE', 'SF':'SF9999.XZCE', 'SM':'SM9999.XZCE', 
                        'SN':'SN9999.XSGE', 'SR':'SR9999.XZCE', 'T':'T9999.CCFX', 'TA':'TA9999.XZCE', 
                        'TC':'TC9999.XZCE', 'TF':'TF9999.CCFX', 'V':'V9999.XDCE', 'WH':'WH9999.XZCE', 
                        'WR':'WR9999.XSGE', 'WS':'WS9999.XZCE', 'WT':'WT9999.XZCE', 'Y':'Y9999.XDCE', 
                        'ZC':'ZC9999.XZCE', 'ZN':'ZN9999.XSGE','AP':'AP9999.XZCE', 
                        'SS':'SS9999.XSGE', 'SP':'SP9999.XSGE', 'SC':'SC9999.XINE', 'UR':'UR9999.XZCE',
                        'EG':'EG9999.XDCE', 'CJ':'CJ9999.XZCE','SA':'SA9999.XZCE','EB':'EB9999.XDCE',
                        'PG':'PG9999.XDCE', 'PF':'PF9999.XZCE','LH':'LH9999.XDCE'}
# class InnerEngine:
#     def __init__(self):
#         self.queue=Queue()
#     def start(self):
#         while True:
#             try:
#                 bar:BarData=self.queue.get(timeout=1)
#                 self.process(bar)
#             except TimeoutError:
#                 continue
#     def process(self,bar:BarData):

class OrderStatus:
    def __init__(self,vt_orderid,price,order_volume=0,traded_volume=0,can_cancel_count=0,fix_size=0):
        """
        因为close使用的是市价单，所以不需要维护撤单和交易数量，也就不需要维护委托数量，所以这里所有的数量都是限价单的
        """
        self.fix_size=fix_size
        self.vt_orderid=vt_orderid
        self.price=price
        self.order_volume=order_volume
        self.traded_volume=traded_volume
        # self.traded_volume2=traded_volume2#2号用于加减，1号用于发单
        self.can_cancel_count=can_cancel_count
        
        
    def __str__(self) -> str:
        return "vt_orderid:{},price:{},order_volume:{},traded_volume:{},can_cancel_count:{}".format(self.vt_orderid,self.price,self.order_volume,self.traded_volume,self.can_cancel_count)
    def __repr__(self) -> str:
        return "vt_orderid:{},price:{},order_volume:{},traded_volume:{},can_cancel_count:{}".format(self.vt_orderid,self.price,self.order_volume,self.traded_volume,self.can_cancel_count)
    def on_open_trade(self,trade:TradeData):
        """
        当成交单传入的时候对策略内部订单对的维护
        """
        
        # self.traded_volume+=trade.volume
        # self.can_cancel_count-=trade.volume    
        print("进入开仓成交，全部成交数量:{},可撤单数量:{}".format(self.traded_volume,self.can_cancel_count))
    def on_close_trade(self,trade:TradeData):
        # self.traded_volume+=trade.volume
        print("进入平仓成交，全部成交数量:{},可撤单数量:{}".format(self.traded_volume,self.can_cancel_count))

    def on_open_order(self,order:OrderData):
        
        self.can_cancel_count=order.volume-order.traded
        self.order_volume=order.volume
        self.traded_volume=order.traded
        # if order.status==Status.NOTTRADED:
        #     # self.can_cancel_count=order.volume
        #     print("进入未成交，can_cancel_count",self.can_cancel_count)
        # if order.status==Status.CANCELLED:
        #     self.can_cancel_count=0
    def on_close_order(self,order:OrderData):
        """
        暂时不care close的订单，或者可以在close订单是完全成交的时候，进行后续操作
        """
        
        self.can_cancel_count=order.volume-order.traded
        self.order_volume=order.volume
        self.traded_volume=order.traded
        
        # if order.status==Status.SUBMITTING:
        #     self.order_volume=order.volume
        # if order.status==Status.NOTTRADED:
        #     self.can_cancel_count=order.volume
        #     self.order_volume=order.volume
        # if order.status==Status.ALLTRADED:
        #     self.can_cancel_count-=order.traded
        #     self.traded_volume=order.traded
            
    
class ComOrder:
    def __init__(self,open_order_status:OrderStatus,close_order_status:OrderStatus=None):
        """
        开仓的状态维护撤单和开仓的成交单，平仓的状态维护平仓的市价单
        """
        self.open_order_status=open_order_status
        self.close_order_status=close_order_status
    # def on_trade(self,trade:TradeData):

    #     if trade.offset==Offset.OPEN:
    #         self.open_order_status.on_open_trade(trade)
    #     if trade.offset==Offset.CLOSE:
    #         # if self.close_order_status==None:
    #         #     raise ValueError("close_not_link")
    #         self.close_order_status.on_close_trade(trade)
    def link(self,close_order_status:OrderStatus):
        self.close_order_status=close_order_status
    
    def on_order(self,order:OrderData):
        if order.offset==Offset.OPEN:
            # self.update_database_orderdata(order)
            return self.open_order_status.on_open_order(order)
        if order.offset==Offset.CLOSE or order.offset == Offset.CLOSETODAY or order.offset==Offset.CLOSEYESTERDAY:
            # self.update_database_orderdata(order)
            if self.close_order_status==None:
                raise ValueError("close_not_link")
                
                # return
            return self.close_order_status.on_close_order(order)
    def is_trade_after_cancel_order(self)->bool:
        """
        当开仓数量=平仓数量+撤单数量，因为现在在撤单里面，所以撤单数量就是can_cancel_count，如果不满足，就是部分成交的时候，撤单先到
        """
        if self.close_order_status==None:
            flag=self.open_order_volume==self.can_cancel_count
        else:
            flag=self.open_order_volume==(self.close_traded_volume+self.can_cancel_count)
        self.open_order_status.can_cancel_count=0#因为收到撤单，所以就直接改成0了，在on_trade里判断方便
        return flag

    def is_trade_after_close_order_all_traded(self)->bool:
        """
        这部分放在on_order里面
        """
        return self.can_cancel_count==0 and self.close_order_status.order_volume==self.close_order_status.traded_volume

    @property
    def open_volume(self):
        return self.open_order_status.fix_size
    @property
    def open_price(self):
        return self.open_order_status.price
    @property
    def close_volume(self):
        return self.close_order_status.fix_size
    @property
    def close_price(self):
        return self.close_order_status.price
    @property
    def open_vt_orderid(self):
        return self.open_order_status.vt_orderid
    @property
    def close_vt_orderid(self):
        return self.close_order_status.vt_orderid
    @property
    def can_cancel_count(self):
        """
        暂时只有开仓的时候可能会撤单
        """
        return self.open_order_status.can_cancel_count
    @property
    def open_order_volume(self):
        return self.open_order_status.order_volume
    
    @property
    def open_traded_volume(self):
        return self.open_order_status.traded_volume
    @property
    def close_traded_volume(self):
        return self.close_order_status.traded_volume

class MyThread(threading.Thread):

    def __init__(self,func,args=()):
        super(MyThread,self).__init__()
        self.func = func
        self.args = args

    def run(self):
        self.result = self.func(*self.args)

    def get_result(self):
        try:
            return self.result  # 如果子线程不使用join方法，此处可能会报没有self.result的错误
        except Exception:
            return None

class MultiFuturesML_ShiPan(CtaTemplate):
    """"""

    author = "用Python的交易员"
    

    
    fixed_size = 1
    pos_=0
    rate=0
    atr_value = 0
    atr_ma = 0
    rsi_value = 0
    rsi_buy = 0
    rsi_sell = 0
    intra_trade_high = 0
    intra_trade_low = 0
    can_enter_short=True
    can_enter_long=True
    flag=False
    gap_base=1
    position=0
    yvalid=None
    parameters = [ 
        "night_start",
        "night_end",
        "bias_second",
        "margin_ratio",
        "size"
    ]
    

    def __init__(self, cta_engine, strategy_name, vt_symbol:str, setting):
        """"""
        
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)
        self.symbol=vt_symbol.split(".")[0]
        
        
        #暂时可以写死
        #用broker_id和账号去定义表名，给策略加两个字段，给它传进去，对所有order都做一次操作
        
        # if db.table_exists(OrderTable):
        #     db.drop_tables([OrderTable])
        


        
        
        
        # order=OrderData(gateway_name='RPC', symbol='ZC109', exchange=Exchange.CZCE, orderid='3_-1987889378_1', ordersysid='', type=OrderType.LIMIT, direction=Direction.LONG, offset=Offset.OPEN, price=890.0, volume=4.0, traded=0, status=Status.SUBMITTING, datetime=None, reference='CtaStrategy_F_ZC109')
        self.trading=True
        self.vt_symbol=vt_symbol
        self.is_cancel_order_trade=True
        self.disconnect_order_list:List[OrderData]=[]
        self.strategy_start_time=datetime.now().replace(tzinfo=pytz.timezone("Asia/Shanghai"))
        self.disconnect=False
        self.is_init_sig_price_use_jq=False
        strategy_parameters=self.get_parameters()
        self.bg_unbias=BarGenerator(self.on_bar_unbias,bias_second=0)
        # self.bg_5min=BarGenerator(self.on_5min_bar,xmin=5)
        bias_second=strategy_parameters["bias_second"]
        self.margin_ratio=strategy_parameters["margin_ratio"]
        self.bg_hf=BarGenerator(self.on_hfbar,xSecond=10,bias_second=1)

        self.bg=BarGenerator(self.on_bar,bias_second=bias_second)
        # self.bg = BarGenerator(self.on_bar,60,self.on_30min_bar)
        # self.am=ArrayManager(799)
        if bias_second<0:
            self.bias_negative_flag=True
        else:
            self.bias_negative_flag=False
        self.signal=0
        self.H15=0
        self.count=0
        self.L15=0
        self.yvalid_flag=False
        self.update_bar_flag=False
        self.night_start:str=strategy_parameters["night_start"]
        self.night_end:str=strategy_parameters["night_end"]
        self.day_start=time(9,0)
        self.day_end=time(15,0)
        if self.night_start and self.night_end:
            self.night_start=time(int(self.night_start.split(":")[0]),int(self.night_start.split(":")[1]))
            self.night_end=time(int(self.night_end.split(":")[0]),int(self.night_end.split(":")[1]))
            self.write_log("夜盘时间为{}-{}".format(self.night_start,self.night_end))
        else:
            self.write_log("无夜盘")
        self.df_flag=False
        self.change_contract=None
        # print(strategy_parameters)
        # self.indicator=pd.read_csv("./data_min/{}_futures_min.csv".format(vt_symbol.replace(".LOCAL","")),index_col=0)
        # self.indicator.index=list(map(lambda x:pd.Timestamp(x,tz='Asia/Shanghai'),pd.to_datetime(self.indicator.index)))
        # self.signal_15=self.indicator["Signal_15"]
        self.capital=20_000
        
        self.can_cancel_count=0
        
        contract_size=strategy_parameters["size"]

        self.fixed_capital=20_000
        # import re
        # symbol=re.match("[A-Z]{1,2}",vt_symbol.upper()).group()
        self.write_log("初始化时候，可以买的大小是{}".format(self.fixed_capital/(self.margin_ratio*contract_size)))
        self.fixed_capital=self.fixed_capital/(self.margin_ratio*contract_size)
    # @db.connection_context()
    # def update_database_orderdata(self,order:OrderData):
    #     if len(OrderTable.select().where(OrderTable.symbol==order.symbol))==0:
    #         # print(len(OrderTable.select().where(OrderTable.symbol=="pb")))
    #         # print("unique")
    #         if order.datetime==None:
    #             order.datetime=""
    #         o=OrderTable(gateway_name=order.gateway_name,
    #                     symbol=order.symbol,
    #                     exchange=order.exchange.value,
    #                     orderid=order.orderid,
    #                     ordersysid=order.ordersysid,
    #                     type=order.type.value,
    #                     direction=order.direction.value,
    #                     offset=order.offset.value,
    #                     price=order.price,
    #                     volume=order.volume,
    #                     traded=order.traded,
    #                     status=order.status.value,
    #                     datetime=order.datetime,
    #                     reference=order.reference)
    #         o.save()
    #     else:
    #         if order.datetime==None:
    #             order.datetime=""
    #         o=OrderTable.update({"symbol":order.symbol,
    #                     "exchange":order.exchange.value,
    #                     "orderid":order.orderid,
    #                     "ordersysid":order.ordersysid,
    #                     "type":order.type.value,
    #                     "direction":order.direction.value,
    #                     "offset":order.offset.value,
    #                     "price":order.price,
    #                     "volume":order.volume,
    #                     "traded":order.traded,
    #                     "status":order.status.value,
    #                     "datetime":order.datetime,
    #                     "reference":order.reference}
    #         ).where(OrderTable.symbol==order.symbol)
    #         o.execute()
    # @db.connection_context()
    # def get_database_orderdata(self,symbol)->Optional[OrderData]:
    #     if len(OrderTable.select().where(OrderTable.symbol==symbol))==0:
    #         return None
    #     else:
    #         o:OrderTable=list(OrderTable.select().where(OrderTable.symbol==symbol))[0]
    #         if o.datetime=="":
    #             o.datetime=None
    #         return OrderData(
    #             gateway_name=o.gateway_name, 
    #             symbol=o.symbol, 
    #             exchange=EXCHANGE_CTP2VT_ST[o.exchange], 
    #             orderid=o.orderid, 
    #             ordersysid=o.ordersysid, 
    #             type=LIMIT_CTP2VT_ST[o.type], 
    #             direction=DIRECTION_CTP2VT_ST[o.direction], 
    #             offset=OFFSET_CTP2VT_ST[o.offset], 
    #             price=o.price, 
    #             volume=o.volume, 
    #             traded=o.traded, 
    #             status=STATUS_CTP2VT_ST[o.status], 
    #             datetime=o.datetime, 
    #             reference=o.reference
    #         )      
    def check_trading_period(self,tick:TickData):

        current_time = tick.datetime.time()

        trading = False
        if (current_time >= self.day_start and current_time <= self.day_end):
            trading=True
        if self.night_start and self.night_end:
            if self.night_end>self.night_start:
                if current_time>=self.night_start and current_time<=self.night_end:
                    trading=True
            else:
                if current_time>=self.night_start or current_time<=self.night_end:
                    trading = True

        return trading
    def on_position(self,position:PositionData):
        
        """        
        PositionData(gateway_name='RPC', symbol='eb2110', exchange=<Exchange.DCE: 'DCE'>, direction=<Direction.SHORT: '空'>, volume=1, frozen=0, price=8917.0, pnl=1020.0, yd_volume=1)
        """
        self.write_log(str(position))
        # if position.vt_symbol!=self.vt_symbol:
        #     """
        #     待取消的函数，主要是为了测试simnow账户
        #     """

        #     return 
        if position.volume==0:
            return 
        vt_orderid=99999999
        open_order_status=OrderStatus(vt_orderid=vt_orderid,price=position.price)
        
        self.comb_status=ComOrder(open_order_status=open_order_status)
        self.comb_status.open_order_status.can_cancel_count=0
        self.comb_status.open_order_status.order_volume=position.volume
        self.comb_status.open_order_status.traded_volume=position.volume
        if position.direction==Direction.LONG:
            self.pos_=1
        if position.direction==Direction.SHORT:
            self.pos_=-1 
        self.trailing_flag=False
        self.position_=0
        self.write_log("读取之前的持仓  \n"+str(position)) 
        # if position.vt_symbol!=self.vt_symbol:
        #     self.change_contract=position.vt_symbol
        # else:
        #     self.change_contract=None

    def on_not_traded_order(self,order:OrderData):
        """
        待取消的函数，或者把函数修改成开盘推送的地方
        """
        self.is_cancel_order_trade=True
        
        # if self.pos_!=0:
        #     self.write_log("既有持仓又有挂单，选择撤单，并且策略接管持仓")
            
        #     self.cancel_order(order.orderid)
        #     return 
        #rpc_server端不接收推送过来的，数据，只在数据库中去查，或者在数据库中查不到的数据，直接就del掉，后面的做法伤害性小，暂定为后面一种做法
        if order.status==Status.NOTTRADED:
            if order not in self.disconnect_order_list:
                self.disconnect_order_list.append(order)
                open_order_status=OrderStatus(vt_orderid=order.vt_orderid,price=order.price)
        
                self.comb_status=ComOrder(open_order_status=open_order_status)

                if order.direction==Direction.LONG:
                    self.pos_=1
                if order.direction==Direction.SHORT:
                    self.pos_=-1 
                self.trailing_flag=False
                self.position_=0
                self.comb_status.on_order(order)
                self.query_order(order.vt_orderid)
                
                self.write_log("读取之前的order，并被策略接管")
                self.write_log(str(order))
            
    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.open_plate_time=datetime.now()
        #bar_count是推送的bar，bars是所有的bar，7是一周
        with open("/root/.vntrader/model_xgb_future_0727_91factor.pkl","rb") as f:
            self.model=pickle.load(f)
        bars=self.load_bar(20)
        """
        Callback of new bar data update.
        """
        
        # print(bars)
        am=ArrayManager(len(bars))

        for bar in bars:
            # print(bar.symbol,"bar",bar.datetime,bar.money,"volume",bar.volume)
            am.update_bar(bar)
            # print(self.am_inited.count)
            
                

        df:pd.DataFrame=pd.DataFrame(np.array([
            am.open,
            am.high,
            am.low,
            am.close,
            am.volume,
            am.open_interest,
            am.money
        ]).T,columns=["open","high","low","close","volume","open_interest","money"],index=am.datetime_array)
        # df:pd.DataFrame=self.create_signal()
        # print(os.getcwd())//root
        
        print(df.index)
        a = df.index[np.logical_and(df.index.hour==21,df.index.minute==1)]
        if len(a)==0:
            a = df.index[np.logical_and(df.index.hour==9,df.index.minute==1)]
        start=a[-8]
        df=df.loc[start:]

        # print(df)
        # df.to_pickle("/root/.vntrader/data/{}_caculate.pkl".format(bar.symbol))
        
        # while not os.path.exists("/root/.vntrader/data/{}_completed.pkl".format(bar.symbol)):
            # time.sleep(0.01)
            # pass
        # while True:
            # try:
                # yvalid=pd.read_pickle("/root/.vntrader/data/{}_completed.pkl".format(bar.symbol))
                # os.remove("/root/.vntrader/data/{}_completed.pkl".format(bar.symbol))
                # break
            # except:
                # continue

        # with open("{}_df.pkl".format(self.symbol),"wb") as f:
        # df.to_pickle("{}_df.pkl".format(self.symbol))
        # self.write_log("品种{}写入完成".format(self.symbol))
        """    def create_signal_long_short_for_model   (yvalid_df):
        yvalid = yvalid_df['yvalid']
        


        temp_lst = []
        t = 0 
        position = pd.DataFrame()
        position['open'] = (yvalid>=0.001)*1
        position['close'] = (yvalid<=-0.001)*-1
        for index,row in position.iterrows():
            if row['open'] == 1:
                temp_lst.append(1)
                t = 1
            elif row['close'] == -1:
                temp_lst.append(-1)    
                t = -1 
            elif row['open']!=1 and row['close'] !=1:
                temp_lst.append(t)
        position['signal'] = temp_lst
        yvalid_df['Signal_1x'] = np.array(position  ['signal'])


        H15 = yvalid.shift(1).rolling(90).max()
        L15 = yvalid.shift(1).rolling(90).min()

        temp_lst = []
        t = 0
        position = pd.DataFrame()
        position['open'] = (yvalid > H15) * 1
        position['close'] = (yvalid < L15) * -1
        for index, row in position.iterrows():
            if row['open'] == 1:
                temp_lst.append(1)
                t = 1
            elif row['close'] == -1:
                temp_lst.append(-1)
                t = -1
            elif row['open'] != 1 and row['close']  != 1:
                temp_lst.append(t)
        position['signal'] = temp_lst
        yvalid_df['Signal_15_fast'] = np.array  (position['signal'])

        yvalid_df['Signal_15_fast_add_1x'] =    yvalid_df['Signal_15_fast'] + yvalid_df    ['Signal_1x']
        yvalid_df['Signal_15_fast_add_1x'][yvalid_df    ['Signal_15_fast_add_1x'] ==-2]=-1
        yvalid_df['Signal_15_fast_add_1x'][yvalid_df    ['Signal_15_fast_add_1x'] ==2]=1

        return yvalid_df"""
        yvalid=self.caculate_signal(df)
        
        temp_lst = []
        t = 0 
        position = pd.DataFrame(index=yvalid.index)
        position['open'] = (yvalid>=0.001)*1
        position['close'] = (yvalid<=-0.001)*-1
        for _,row in position.iterrows():
            if row['open'] == 1:
                temp_lst.append(1)
                t = 1
            elif row['close'] == -1:
                temp_lst.append(-1)    
                t = -1 
            elif row['open']!=1 and row['close'] !=-1:
                temp_lst.append(t)
        position['signal'] = temp_lst
        Signal_1x= position['signal']

        H15 = yvalid.shift(1).rolling(90).max()
        L15 = yvalid.shift(1).rolling(90).min()
        temp_lst = []
        t = 0
        position = pd.DataFrame(index=yvalid.index)
        position['open'] = (yvalid > H15) * 1
        position['close'] = (yvalid < L15) * -1
        
        for _, row in position.iterrows():
            if row['open'] == 1:
                temp_lst.append(1)
                t = 1
            elif row['close'] == -1:
                temp_lst.append(-1)
                t = -1
            elif row['open'] != 1 and row['close']  != -1:
                temp_lst.append(t)
        position['signal'] = temp_lst
        Signal_15_fast = position['signal']

        Signal_15_fast_add_1x =   Signal_15_fast + Signal_1x
        Signal_15_fast_add_1x[Signal_15_fast_add_1x ==-2]=-1
        Signal_15_fast_add_1x[Signal_15_fast_add_1x ==2]=1

        self.signal=Signal_15_fast_add_1x.iloc[-1]
        """
        待定
        """
        self.Signal_1x=Signal_1x.iloc[-1]
        self.Signal_15_fast=Signal_15_fast.iloc[-1]
        self.H15=H15.iloc[-1]
        self.L15=L15.iloc[-1]
        Signal:pd.Series=Signal_15_fast_add_1x.diff(1)
        print(Signal)
        date_=Signal.where(Signal!=0).dropna().index[-1]
        print(date_)
        self.sig_chg_price=df.loc[date_,"close"]
        self.write_log("信号初始化完成，当前品种为{},信号为{},Signal_15_fast为{},Signal_1x为{},H15:{},L15:{},信号反转时的价格是：{}".format(bar.symbol,self.signal,self.Signal_15_fast,self.Signal_1x,self.H15,self.L15,self.sig_chg_price))
        self.write_log("策略初始化")
        # start=a[-4]
        i=1
        #如果对速度有影响可以再优化
        while len(df.loc[a[-1*i]:])<500*3:
            i+=1
        else:
            self.df=df.loc[a[-1*i]:]
        print(self.df)
        self.min5_flag=False
        if self.check_trading_period(bar):
            self.write_log("盘中启动")
            self.min5_flag=True
        #明天重新修改，不能直接判断
        # self.am_inited=ArrayManager(len(df),mode="min")

        
        # self.rsi_buy = 50 + self.rsi_entry
        # self.rsi_sell = 50 - self.rsi_entry

        # self.load_bar(3)
        # self.load_tick(3)
    # def load_bar(self,callback=None):
    #     if callback==None:
    #         callback=self.on_bar
    #     bar=1
        
    #     callback(bar)
    def on_connect(self):
        self.strategy_start_time=datetime.now().replace(tzinfo=pytz.timezone("Asia/Shanghai"))
        self.is_init_sig_price_use_jq=False
        self.write_log("我连接上了，所以重新修改strategy_start_time到{}".format(self.strategy_start_time))

    def on_disconnect(self):
        self.strategy_disconnect_time=datetime.now().replace(tzinfo=pytz.timezone("Asia/Shanghai"))
        self.disconnect=True
        self.write_log("disconnect时间为{}".format(self.strategy_disconnect_time))
        self.disconnect_order_list:List[OrderData]=[]

    def on_start(self):
        """
        Callback when strategy is started.
        """
        # order=self.get_database_orderdata(self.symbol)
        # ##这个调用在后面一些
        # if order:
        #     if order.offset==Offset.OPEN:
        #         if order.is_active():
        #             self.on_not_traded_order(order)
        #         elif order.status==Status.ALLTRADED:
        #             position=PositionData(
        #                 gateway_name=order.gateway_name,
        #                 symbol=order.symbol,
        #                 exchange=order.exchange,
        #                 direction=order.direction,
        #                 volume=order.volume,
        #                 frozen=0,
        #                 yd_volume=order.volume,
        #                 pnl=0
        #             )
        #             self.on_position(position)
        # print("self.trading",self.trading)
        # self.write_log("策略启动")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log(str("最终的仓位应该是0",self.position))
        
        self.write_log("策略停止")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        # print(tick.vt_symbol,tick.datetime,datetime.now().replace(tzinfo=pytz.timezone("Asia/Shanghai")))
        # self.write_log(str(tick.datetime))
        if not self.check_trading_period(tick):
            return
        self.limit_up=tick.limit_up
        self.limit_down=tick.limit_down
        # self.flag=True
        # self.write_log(str(tick.symbol,"tick",tick.datetime,tick.money, "volume",tick.volume)
        self.bg.update_align_tick(tick)
        self.bg_unbias.update_align_tick(tick)
        # self.bg.update_sharp_tick(tick)#这个版本的bar可以任意时刻打开，而且倾向于任意时刻打开
        self.bg_hf.update_hfBar(tick)
        
        # self.bg_hf.update_tick(tick)
        
        # print(tick)
    def vtsymbol_to_jqsymbol(self,vt_symbol):
        symbol=re.match("[A-Z]{1,2}",vt_symbol.upper()).group()
        code=future_code_dict[symbol]
        date_=re.search("[0-9]{3,4}",vt_symbol.upper()).group()
        if len(date_)==3:
            date_="2"+date_
        code=future_code_dict[symbol]
        if "8888" in code:
            code=code.replace("8888",date_)
        if "9999" in code:
            code=code.replace("9999",date_)
        return code
    def on_hfbar(self,hfbar:BarData):
        """
        必须提前启动，不然很可能出问题(现在不需要提前启动)
        """
        
        if self.yvalid_flag and hfbar.datetime.second>20 and hfbar.datetime.second<40:
            self.write_log(str(hfbar))
            self.yvalid=self.caculate_signal(self.df.copy())
            self.H15 = self.yvalid.rolling(90).max().iloc[-1]
            self.L15 = self.yvalid.rolling(90).min().iloc[-1]
            self.write_log("更新self.H15和self.L15到，H15：{}，L15：{}".format(self.H15,self.L15))
            self.yvalid_flag=False
        if self.update_bar_flag and hfbar.datetime.second>20 and hfbar.datetime.second<40:

            self.update_bar_flag=False
            code=self.vtsymbol_to_jqsymbol(hfbar.vt_symbol)
            try:
                if not self.disconnect:
                    bars:pd.DataFrame=diewei.get_price(code,start_date=str(hfbar.datetime.replace(second=0,microsecond=0)-timedelta(minutes=5))[:19],end_date=str(hfbar.datetime.replace(second=0,microsecond=0))[:19],frequency='1m',fields=['open','high','low','close','volume','money','open_interest'])
                else:
                    timedelta_connect_and_disconnect=(self.strategy_start_time-self.strategy_disconnect_time).seconds//60+1
                    self.write_log("断线大约{}分钟".format(timedelta_connect_and_disconnect))
                    self.disconnect=False
                    bars:pd.DataFrame=diewei.get_price(code,start_date=str(hfbar.datetime.replace(second=0,microsecond=0)-timedelta(minutes=timedelta_connect_and_disconnect+5))[:19],end_date=str(hfbar.datetime.replace(second=0,microsecond=0))[:19],frequency='1m',fields=['open','high','low','close','volume','money','open_interest'])
            except Exception as e:
                self.write_log("on_hfbar里出现错误:"+str(e)+" 所以return")
                return 
            bars_list:List[BarData]=[]
            for index,bar in bars.iterrows():
                symbol,_=hfbar.vt_symbol.split(".")
                bars_list.append(
                        BarData(
                        gateway_name="RPC",
                        symbol=symbol,
                        exchange=hfbar.exchange,
                        interval="1m",
                        datetime=index.replace(tzinfo=pytz.timezone("Asia/Shanghai")),
                        volume=bar["volume"],
                        money=bar["money"],
                        open_price=bar["open"],
                        close_price=bar["close"],
                        high_price=bar["high"],
                        low_price=bar["low"],
                        open_interest=bar["open_interest"]
                    )
                )

            for bar in bars_list:
                # bar_temp=pd.DataFrame([[bar.open_price,bar.high_price,bar.low_price,bar.close_price,bar.volume,bar.open_interest,bar.money/self.margin_ratio]],columns=["open","high","low","close","volume","open_interest","money"],index=[bar.datetime])
                self.df.loc[bar.datetime]=[bar.open_price,bar.high_price,bar.low_price,bar.close_price,bar.volume,bar.open_interest,bar.money]
            
            #排个序
            self.df.sort_index(inplace=True)
            yvalid=self.caculate_signal(self.df)
        
            temp_lst = []
            t = 0 
            position = pd.DataFrame(index=yvalid.index)
            position['open'] = (yvalid>=0.001)*1
            position['close'] = (yvalid<=-0.001)*-1
            for _,row in position.iterrows():
                if row['open'] == 1:
                    temp_lst.append(1)
                    t = 1
                elif row['close'] == -1:
                    temp_lst.append(-1)    
                    t = -1 
                elif row['open']!=1 and row['close'] !=-1:
                    temp_lst.append(t)
            position['signal'] = temp_lst
            Signal_1x= position['signal']
            H15 = yvalid.shift(1).rolling(90).max()
            L15 = yvalid.shift(1).rolling(90).min()
            temp_lst = []
            t = 0
            position = pd.DataFrame(index=yvalid.index)
            position['open'] = (yvalid > H15) * 1
            position['close'] = (yvalid < L15) * -1
            
            for _, row in position.iterrows():
                if row['open'] == 1:
                    temp_lst.append(1)
                    t = 1
                elif row['close'] == -1:
                    temp_lst.append(-1)
                    t = -1
                elif row['open'] != 1 and row['close']  != -1:
                    temp_lst.append(t)
            position['signal'] = temp_lst
            Signal_15_fast = position['signal']

            Signal_15_fast_add_1x =   Signal_15_fast + Signal_1x
            Signal_15_fast_add_1x[Signal_15_fast_add_1x ==-2]=-1
            Signal_15_fast_add_1x[Signal_15_fast_add_1x ==2]=1

            # self.signal=Signal_15_fast_add_1x.iloc[-1]
            # self.Signal_1x=Signal_1x.iloc[-1]
            # self.Signal_15_fast=Signal_15_fast.iloc[-1]
            # self.H15=H15.iloc[-1]
            # self.L15=L15.iloc[-1]
            Signal:pd.Series=Signal_15_fast_add_1x.diff(1)
            print(Signal)
            date_=Signal.where(Signal!=0).dropna().index[-1]
            print(date_)
            self.sig_chg_price=self.df.loc[date_,"close"]

            """
            暂时不更改信号，只在on_bar里更改信号，这里只更改价格
            """
            self.write_log("信号每分钟重新计算一次，保证信号反转时价格时正确的，当前品种为{},信号为{},Signal_15_fast为{},Signal_1x为{},H15:{},L15:{},信号反转时的价格是:{},bar的时间是:{},此时的pos是{}".format(hfbar.symbol,self.signal,self.Signal_15_fast,self.Signal_1x,self.H15,self.L15,self.sig_chg_price,str(hfbar.datetime.replace(second=0,microsecond=0)),self.pos_))
            
            """
            初始化聚宽数据
            """
            
            self.is_init_sig_price_use_jq=True
            if hfbar.datetime.replace(microsecond=0,second=0).time()==time(14,58):
                DIR_PATH=str(bar.datetime)[:10]
                if not os.path.exists(DIR_PATH):
                    os.mkdir(DIR_PATH)
                FILE_PATH=os.path.join(DIR_PATH,self.vtsymbol_to_jqsymbol(hfbar.vt_symbol))
                GLOB_FILE_PATH=os.path.join(DIR_PATH,"*_real.txt")
                with open(FILE_PATH+"_real"+".txt","w") as f:
                    f.write(str(self.signal))
            self.write_log("5分钟到了bar更新,并打印最后10分钟的数据")                
            self.write_log(str(self.df.tail(10)))
            print("hfbar",hfbar.datetime,hfbar.money,"volume",hfbar.volume)
        try:
            if hfbar.datetime.second>=40 and hfbar.datetime.second<=59:
                
                DIR_PATH=str(hfbar.datetime)[:10]
                columns=['JM2109.XDCE', 'CU2108.XSGE', 'ZN2108.XSGE', 'SR2109.XZCE', 'AL2108.XSGE', 'JM2109.XDCE', 'SM2109.XZCE', 'CS2109.XDCE', 'SP2109.XSGE', 'AP2110.XZCE', 'OI2109.XZCE', 'SF2109.XZCE', 'CF2109.XZCE', 'PB2108.XSGE', 'NI2108.XSGE', 'EG2109.XDCE', 'RM2109.XZCE', 'MA2109.XZCE', 'BU2109.XSGE', 'SS2108.XSGE', 'CJ2109.XZCE', 'TA2109.XZCE', 'V2109.XDCE', 'HC2110.XSGE', 'I2109.XDCE', 'PG2108.XDCE', 'CJ2109.XZCE', 'PP2109.XDCE', 'SA2109.XZCE', 'EB2108.XDCE', 'RB2110.XSGE', 'Y2109.XDCE', 'RU2109.XSGE', 'UR2109.XZCE', 'JD2109.XDCE', 'AP2110.XZCE', 'FU2109.XSGE', 'AP2110.XZCE']
                if os.path.exists(DIR_PATH):
                    restrict_count=15
                    signal_sum=0
                    GLOB_FILE_PATH=os.path.join(DIR_PATH,"*_real.txt")
                    for file_name in glob.glob(GLOB_FILE_PATH):
                        with open(file_name,"r") as f:
                            for line in f:
                                signal=int(line.strip())
                                signal_sum+=signal
                    
                    if signal_sum<=-1*restrict_count:
                        
                        
                        for column in columns:
                            if os.path.exists(os.path.join(DIR_PATH,column+"_real.txt")):
                                with open(os.path.join(DIR_PATH,column+"_real.txt"),"r") as     f:
                                    for line in f:
                                        signal=int(line.strip())
                                if signal==-1:
                                    signal=0#按column顺序选restrict_count个
                                    signal_sum+=1
                                    self.write_log(column+"限制开空仓")
                                    with open(os.path.join(DIR_PATH,column+".txt"),"w") as  f_tmp:
                                        """
                                        仅仅创建，不用写东西
                                        """
                                        pass
                                    if signal_sum>-1*restrict_count:
                                        break
                        
                    if signal_sum>=restrict_count:
                        for column in columns:
                            if os.path.exists(os.path.join(DIR_PATH,column+"_real.txt")):
                                with open(os.path.join(DIR_PATH,column+"_real.txt"),"r") as     f:
                                    for line in f:
                                        signal=int(line.strip())
                                if signal==1:
                                    signal=0#按column顺序选restrict_count个
                                    signal_sum-=1
                                    self.write_log(column+"限制开多仓")
                                    with open(os.path.join(DIR_PATH,column+".txt"),"w") as  f_tmp:
                                        """
                                        仅仅创建，不用写东西
                                        """
                                        pass
                                    if signal_sum<restrict_count:
                                        break
        except Exception as e:
            self.write_log("文件读取失败:原因是"+str(e))                        
            # def write_log(self, msg: str):
            #     print(msg)
            # def run_on_bar(self,bar:BarData):
            # def parallel_on_bar(self,bar:BarData):
                # start_time=time.time()
                
    def on_bar_unbias(self,bar:BarData):
        
        # self.am.update_bar(bar)
        # print(self.am.count)
        # if not self.am.inited:
        #     if os.path.exists("/root/.vntrader/data/{}_completed.pkl".format(bar.symbol)):
        #         os.remove("/root/.vntrader/data/{}_completed.pkl".format(bar.symbol))
        #     # print("我还没有初始化好")
        #     return 
        bar_temp=pd.DataFrame([[bar.open_price,bar.high_price,bar.low_price,bar.close_price,bar.volume,bar.open_interest,bar.money/self.margin_ratio]],columns=["open","high","low","close","volume","open_interest","money"],index=[bar.datetime])
        print(bar.money,"bar.money")
        print(self.margin_ratio)
        print(bar_temp)
        self.df=pd.concat((self.df,bar_temp))        
        self.df=self.df.sort_index(ascending=True)
        self.yvalid_flag=True
    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """

        print(bar.symbol,"bar",bar.datetime,bar.money,"volume",bar.volume,"当前时间:",datetime.now().replace(tzinfo=pytz.timezone("Asia/Shanghai")))
        

           
        self.update_bar_flag=True#这里用来使用聚宽的数据更新，但这个只是更改flag，真正的更新还是在hfbar里面
        if bar.datetime.time()==time(15,0) or bar.datetime.time()==self.night_end: 
            self.is_cancel_order_trade=False
            self.cancel_all()
            self.write_log("时间到了，所以全部撤单")
            return 
        if not self.trading:
            self.write_log("策略没有完成初始化，把trading设为True")
            return 
        
        # if not self.am.inited:
        #     if os.path.exists("/root/.vntrader/data/{}_completed.pkl".format(bar.symbol)):
        #         os.remove("/root/.vntrader/data/{}_completed.pkl".format(bar.symbol))
            # print("我还没有初始化好")
            # return 
        # df:pd.DataFrame=pd.DataFrame(np.array([
        #     self.am.open,
        #     self.am.high,
        #     self.am.low,
        #     self.am.close,
        #     self.am.volume,
        #     self.am.open_interest,
        #     self.am.money
        # ]).T,columns=["open","high","low","close","volume","open_interest","money"],index=self.am.datetime_array)
        # df:pd.DataFrame=self.create_signal()
        # print(os.getcwd())//root
        # bar_=pd.DataFrame(np.array([[bar.open_price],[bar.high_price],[bar.low_price],[bar.close_price],[bar.volume],[bar.open_interest],[bar.money]]).T,columns=["open","high","low","close","volume","open_interest","money"],index=[bar.datetime])

        
        print(self.margin_ratio)
        bar_temp=pd.DataFrame([[bar.open_price,bar.high_price,bar.low_price,bar.close_price,bar.volume,bar.open_interest,bar.money/self.margin_ratio]],columns=["open","high","low","close","volume","open_interest","money"],index=[bar.datetime])
        # print(bar_temp)
        # print(self.df)
        yvalid_current=self.caculate_signal_one_line(pd.concat((self.df.copy(),bar_temp)))
        
        if self.H15 and self.L15:
            
            # yvalid_current=yvalid.iloc[-1]
            open=(yvalid_current>=0.001)*1
            close=(yvalid_current<=-0.001)*-1
            if open==1:
                self.Signal_1x=1
            elif close==-1:
                self.Signal_1x=-1
            
            
            open=(yvalid_current>self.H15)*1
            close=(yvalid_current<self.L15)*-1
            if open==1:
                self.Signal_15_fast=1
                
            elif close==-1:
                self.Signal_15_fast=-1
            Signal_15_fast_add_1x=self.Signal_15_fast+self.Signal_1x
            if Signal_15_fast_add_1x==2:
                Signal_15_fast_add_1x=1
            if Signal_15_fast_add_1x==-2:
                Signal_15_fast_add_1x=-1
            if self.signal!=Signal_15_fast_add_1x:
                self.sig_chg_price=bar.close_price
            self.signal=Signal_15_fast_add_1x
        if bar.datetime.time()==time(14,59):
            DIR_PATH=str(bar.datetime)[:10]
            if os.path.exists(DIR_PATH):
                self.write_log("存在文件夹{}".format(DIR_PATH))
                if os.path.exists(os.path.join(DIR_PATH,self.vtsymbol_to_jqsymbol(bar.vt_symbol)+'.txt')):
                    
                    self.signal=0
                    self.write_log("存在文件{}，并把信号放置为0".format(os.path.join(DIR_PATH,self.vtsymbol_to_jqsymbol(bar.vt_symbol)+'.txt')))
        # self.write_log("symbol: "+str(bar.symbol)+" exchange: "+str(bar.exchange)+" signal是  "+str(self.signal)+" "+str(datetime.now()))#交易代码全在这里面
        # self.signal=0
        
        self.fixed_size=int(self.fixed_capital/self.sig_chg_price)
        # if self.fixed_size>1:
        #     self.fixed_size=1
        self.write_log("可以购买的数量是:{}".format(self.fixed_size))
        """
        虽然时间没到，但一定要算信号，每分钟从聚宽拿一次数据，这样第二分钟，信号计算就是正确的了，而且价格也是正确的
        """
        # flag1=(bar.datetime-self.strategy_start_time).total_seconds()<=5*60
        flag2=self.is_init_sig_price_use_jq 
        flag3=bar.datetime.time()==time(9,1) or bar.datetime.time()==time(10,31) or bar.datetime.time()==time(21,1) or bar.datetime.time()==time(13,31)
        
        if (not flag2) and (not flag3):
            self.write_log("没有初始化聚宽数据")
            return 
        if self.fixed_size==0:
            self.write_log("买不起，所以return")
            return 
        # self.write_log("symbol:{},time:{}".format(bar.symbol,time.time()-start_time))     
        # print("symbol: "+str(bar.symbol))
# -----------------------------------------------
        
        
        """
        实盘交易代码
        """
        """
        撤单的逻辑要放在开仓的逻辑之前，不然按照现在的逻辑会出问题
        """
        
        if self.signal==1 and self.pos_==-1 and self.comb_status.can_cancel_count>0:
            
            # self.cancel_order(self.comb_status.open_orderid)
            self.is_cancel_order_trade=True
            self.comb_status.open_order_status.price=self.sig_chg_price#改变价格为bar.close_price方便收到撤销回报后，立刻发单        #开仓单这一条线维护的价格
            self.comb_status.open_order_status.fix_size=self.fixed_size#开仓单这一条线维护的数量
            print("撤单发单量",self.comb_status.open_volume)
            self.position_=0
            if self.comb_status.open_traded_volume==0:
                self.pos_=1
                self.write_log("未成交撤单")
            else:
                self.write_log("部分成交撤单")
            self.trailing_flag=False
            self.cancel_order(self.comb_status.open_vt_orderid)
            self.write_log("撤单空，再发多单")

        if self.signal==-1 and self.pos_==1 and self.comb_status.can_cancel_count>0:
            
            # self.cancel_order(self.comb_status.open_orderid)
            self.comb_status.open_order_status.price=self.sig_chg_price
            self.is_cancel_order_trade=True

            self.comb_status.open_order_status.fix_size=self.fixed_size
            print("撤单发单量",self.comb_status.open_volume)
            
            self.write_log(bar.datetime)
            self.write_log(bar.datetime.hour)
            self.trailing_flag=False
            self.position_=0
            if self.comb_status.open_traded_volume==0:
                self.pos_=-1
                self.write_log("未成交撤单")
            else:
                self.write_log("部分成交撤单")
            
            self.cancel_order(self.comb_status.open_vt_orderid)
            self.write_log("撤单多，再发空单")
        if self.signal==0 and self.pos_==1 and self.comb_status.can_cancel_count>0:
            self.is_cancel_order_trade=True
            
            self.write_log(bar.datetime)
            self.write_log(bar.datetime.hour)
            self.trailing_flag=False
            self.position_=0
            if self.comb_status.open_traded_volume==0:
                self.pos_=0
                self.write_log("未成交撤单")
            else:
                self.write_log("部分成交撤单")
            self.can_enter_long=False
            self.can_enter_short=False
            self.cancel_order(self.comb_status.open_vt_orderid)
            self.write_log("撤单多，不发单")
        if self.signal==0 and self.pos_==-1 and self.comb_status.can_cancel_count>0:
            self.is_cancel_order_trade=True
            self.write_log(bar.datetime)
            self.write_log(bar.datetime.hour)
            self.trailing_flag=False
            self.position_=0
            if self.comb_status.open_traded_volume==0:
                self.pos_=0
                self.write_log("未成交撤单")
            else:
                self.write_log("部分成交撤单")
            self.can_enter_long=False
            self.can_enter_short=False
            self.cancel_order(self.comb_status.open_vt_orderid)      
            self.write_log("撤单空，不发单") 

        if self.signal==1 and self.pos_==0 and self.can_enter_long:
            vt_orderid=self.buy(self.sig_chg_price, self.fixed_size)[0]
            open_order_status=OrderStatus(vt_orderid=vt_orderid,price=self.sig_chg_price)#开仓的orderid记录在open_orderid
            self.comb_status=ComOrder(open_order_status=open_order_status)
            # self.fixed_size1=self.fixed_size
            self.write_log("进入多")
            self.write_log(bar.datetime)
            self.write_log(bar.datetime.hour)
            self.trailing_flag=False
            self.position_=0
            self.pos_=1

        # # 做空：挂单高卖千1
        if self.signal==-1 and self.pos_==0 and self.can_enter_short:
            self.fixed_size1=self.fixed_size
            vt_orderid=self.short(self.sig_chg_price,self.fixed_size)[0]
            open_order_status=OrderStatus(vt_orderid=vt_orderid,price=self.sig_chg_price)
            self.comb_status=ComOrder(open_order_status)
            self.write_log("进入空")
            self.write_log(bar.datetime)
            self.write_log(bar.datetime.hour)
            self.trailing_flag=False
            self.position_=0
            self.pos_=-1
        

        # """
        # 限价单撤单再发单的处理
        # """
        # self.write_log("可以撤单的数量:{}".format(self.comb_status.can_cancel_count))
        # 做多：挂单低买千1
        """
        先平仓，再转头开仓
        """
        # self.write_log("open_traded_volume:{}".format(self.comb_status.open_traded_volume))
        if self.signal==1 and self.pos_==-1 and self.comb_status.open_traded_volume>0: 
            if self.change_contract:
                vt_orderid=self.cover(self.limit_up,self.comb_status.open_traded_volume,specific_symbol=self.change_contract)[0]
                self.change_contract=None
                self.write_log("换月平仓")
            else:
                vt_orderid=self.cover(self.limit_up,self.comb_status.open_traded_volume)[0]
            self.write_log("cover")
            close_order_status=OrderStatus(vt_orderid=vt_orderid,price=self.sig_chg_price,fix_size=self.fixed_size)#平仓是正常出场，把平仓的orderid存在close_orderid里，这样子，一个OrderStatus就对应了一次正常的开平仓，再收到所有平仓的回报后，反手开仓，这时候选择重新初始化OrderStatus
            self.comb_status.link(close_order_status)
            # """
            # 待验证
            # """
            # self.comb_status.open_order_status.traded_volume=0
            # self.order_status.volume=self.fixed_size
            
            self.trailing_flag=False
            self.position_=0
            self.pos_=1

        # 做空：挂单高卖千1
        
        if self.signal==-1 and self.pos_==1 and self.comb_status.open_traded_volume>0:
            if self.change_contract:
                vt_orderid=self.sell(self.limit_down,self.comb_status.open_traded_volume,specific_symbol=self.change_contract)[0]
                self.change_contract=None
                self.write_log("换月平仓")
            else:
                vt_orderid=self.sell(self.limit_down,self.comb_status.open_traded_volume)[0]

            self.write_log("sell")
            close_order_status=OrderStatus(vt_orderid=vt_orderid,price=self.sig_chg_price,fix_size=self.fixed_size)
            self.comb_status.link(close_order_status)
            # self.comb_status.open_order_status.traded_volume=0
            self.trailing_flag=False
            self.position_=0
            self.pos_=-1
        
        if self.signal==0 and self.pos_==1 and self.comb_status.open_traded_volume>0:
            if self.change_contract:
                vt_orderid=self.sell(self.limit_down,self.comb_status.open_traded_volume,specific_symbol=self.change_contract)[0]
                self.change_contract=None
                self.write_log("换月平仓")
            else:
                vt_orderid=self.sell(self.limit_down,self.comb_status.open_traded_volume)[0]
           
            self.write_log("sell")
            close_order_status=OrderStatus(vt_orderid=vt_orderid,price=self.sig_chg_price,fix_size=self.fixed_size)
            self.comb_status.link(close_order_status)
            # self.comb_status.open_order_status.traded_volume=0
            self.trailing_flag=False
            self.position_=0
            self.pos_=0
            self.can_enter_long=False
            self.can_enter_short=False
        
        if self.signal==0 and self.pos_==-1 and self.comb_status.open_traded_volume>0:
            if self.change_contract:
                vt_orderid=self.cover(self.limit_up,self.comb_status.open_traded_volume,specific_symbol=self.change_contract)[0]
                self.change_contract=None
            else:
                vt_orderid=self.cover(self.limit_up,self.comb_status.open_traded_volume)[0]
            self.write_log("cover")
            close_order_status=OrderStatus(vt_orderid=vt_orderid,price=self.sig_chg_price,fix_size=self.fixed_size)
            self.comb_status.link(close_order_status)
            # self.comb_status.open_order_status.traded_volume=0
            self.trailing_flag=False
            self.position_=0
            self.pos_=0
            self.can_enter_long=False
            self.can_enter_short=False
        
        self.write_log("symbol: "+str(bar.symbol)+" exchange: "+str(bar.exchange)+" signal是  "+str(self.signal)+" "+str(datetime.now())+"bar的时间是"+str(bar.datetime))#交易代码全在这里面
        # self.yvalid=yvalid
        
         
        # 进入止损逻辑
        # if self.flag: 
            # print("进入flag")
            # print(self.pos_)
            # self.am.update_bar(bar)
            # if self.high_price<bar.high_price:
                # self.high_price=bar.high_price
            # print(self.am.count)
            # if self.pos_==1 and self.position_==1:
                # self.rate=bar.close_price/self.price_complete-1
                # print(self.rate)
                
            # elif self.pos_==-1 and self.position_==-1:
                # self.rate=self.price_complete/bar.close_price-1
            
                # print(self.rate)
            # self.position_time=bar.datetime-self.start_time
            
            # print(self.position_time.seconds)
            # if self.position_time.seconds>6*3600:
            #     if self.pos_==1:
            #         self.sell(bar.close_price - 5,self.fixed_size)
            #         self.write_log("时间止损")
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #     if self.pos_==-1:
            #         self.cover(bar.close_price + 5,self.fixed_size)
            #         self.write_log("时间止损")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False

            # if self.rate<=-0.05 or self.rate>=0.05:
            #     if self.pos_==1 and self.position_==1:
            #         self.sell(bar.close_price*0.97,self.order_status.traded_volume)
            #         self.order_status=OrderStatus(orderid=orderid,price=bar.close_price)
            #         self.write_log("sell止损")
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #     if self.pos_==-1 and self.position_==-1:
            #         self.cover(bar.close_price*1.03,self.order_status.traded_volume)
            #         self.order_status=OrderStatus(orderid=orderid,price=bar.close_price)
            #         self.write_log("cover止损")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False

            # """
            # 延迟时间止损+固定止损
            # """
            
            # if self.rate<-0.01*self.gap_base and self.position_time.seconds>15*60:
                
            #     if self.pos_==1:
            #         print("固定止损")
            #         self.sell(bar.close_price - 5,self.fixed_size1)
            #         self.write_log("sell固定止损")
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #         self.flag=False
            #         self.trailing_flag=False
            #     if self.pos_==-1:
            #         print("固定止损")
            #         self.cover(bar.close_price + 5,self.fixed_size1)
            #         self.write_log("cover固定止损")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False
            #         self.flag=False
            #         self.trailing_flag=False
            # # # if self.price_complete<self.trailing_percent:
            # # #     print(True)
            # if self.trailing_flag:
            #     if self.pos_==1 and max(self.trailing_point_sell,self.price_complete*(1-0.01*self.gap_base))>bar.close_price:
            #         print("sell移动止损")
            #         self.sell(bar.close_price - 5,self.fixed_size1)
            #         self.write_log("sell移动止损")
                    
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #         self.flag=False
            #         self.trailing_flag=False
            #     if self.pos_==-1 and min(self.trailing_point_cover,self.price_complete*(1+0.01*self.gap_base))<bar.close_price:
            #         print("cover移动止损")
            #         self.cover(bar.close_price + 5,self.fixed_size1)
            #         self.write_log("cover移动止损")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False
            #         self.flag=False
            #         self.trailing_flag=False
            # if self.rate>0.09:
            #     if self.pos_==1:
            #         self.sell(bar.close_price - 5,self.fixed_size1)
            #         self.write_log("sell止盈")
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #         self.flag=False
            #         self.trailing_flag=False
            #     if self.pos_==-1:
            #         self.cover(bar.close_price + 5,self.fixed_size1)
            #         self.write_log("cover止盈")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False
            #         self.flag=False
            #         self.trailing_flag=False

        # atr_array = am.atr(self.atr_length, array=True)
        # self.atr_value = atr_array[-1]
        # self.atr_ma = atr_array[-self.atr_ma_length:].mean()
        # self.rsi_value = am.rsi(self.rsi_length)

        # if self.pos == 0:
        #     self.intra_trade_high = bar.high_price
        #     self.intra_trade_low = bar.low_price

        #     if self.atr_value > self.atr_ma:
        #         if self.rsi_value > self.rsi_buy:
        #             self.buy(bar.close_price + 5, self.fixed_size)
        #         elif self.rsi_value < self.rsi_sell:
        #             self.short(bar.close_price - 5, self.fixed_size)

        # elif self.pos > 0:
        #     self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
        #     self.intra_trade_low = bar.low_price

        #     long_stop = self.intra_trade_high * \
        #         (1 - self.trailing_percent / 100)
        #     self.sell(long_stop, abs(self.pos), stop=True)

        # elif self.pos < 0:
        #     self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
        #     self.intra_trade_high = bar.high_price

        #     short_stop = self.intra_trade_low * \
        #         (1 + self.trailing_percent / 100)
        #     self.cover(short_stop, abs(self.pos), stop=True)
        
        self.put_event()
# -----------------------------------------------
        
        
        """
        止损逻辑，暂时没用上
        """
        # if self.flag:
        #     # print("进入flag")
        #     # print(self.pos_)
        #     # self.am.update_bar(bar)
        #     if self.high_price<bar.high_price:
        #         self.high_price=bar.high_price
        #     # print(self.am.count)
        #     if self.pos_==1:
        #         self.rate=bar.close_price/self.price_complete-1
        #         # print(self.rate)
                
        #     elif self.pos_==-1:
        #         self.rate=self.price_complete/bar.close_price-1
            
        #         # print(self.rate)
        #     self.position_time=bar.datetime-self.start_time
            # print(self.position_time.seconds)
            # if self.position_time.seconds>6*3600:
            #     if self.pos_==1:
            #         self.sell(bar.close_price - 5,self.fixed_size)
            #         self.write_log("时间止损")
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #     if self.pos_==-1:
            #         self.cover(bar.close_price + 5,self.fixed_size)
            #         self.write_log("时间止损")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False

            # if self.rate<-0.01:
            #     if self.pos_==1:
            #         self.sell(bar.close_price - 5,self.fixed_size)
            #         self.write_log("sell止损")
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #     if self.pos_==-1:
            #         self.cover(bar.close_price + 5,self.fixed_size)
            #         self.write_log("cover止损")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False
            # """
            # 延迟时间止损+固定止损
            # """
            
            # if self.rate<-0.01*self.gap_base and self.position_time.seconds>15*60:
                
            #     if self.pos_==1:
            #         print("固定止损")
            #         self.sell(bar.close_price - 5,self.fixed_size1)
            #         self.write_log("sell固定止损")
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #         self.flag=False
            #         self.trailing_flag=False
            #     if self.pos_==-1:
            #         print("固定止损")
            #         self.cover(bar.close_price + 5,self.fixed_size1)
            #         self.write_log("cover固定止损")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False
            #         self.flag=False
            #         self.trailing_flag=False
            # # # if self.price_complete<self.trailing_percent:
            # # #     print(True)
            # if self.trailing_flag:
            #     if self.pos_==1 and max(self.trailing_point_sell,self.price_complete*(1-0.01*self.gap_base))>bar.close_price:
            #         print("sell移动止损")
            #         self.sell(bar.close_price - 5,self.fixed_size1)
            #         self.write_log("sell移动止损")
                    
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #         self.flag=False
            #         self.trailing_flag=False
            #     if self.pos_==-1 and min(self.trailing_point_cover,self.price_complete*(1+0.01*self.gap_base))<bar.close_price:
            #         print("cover移动止损")
            #         self.cover(bar.close_price + 5,self.fixed_size1)
            #         self.write_log("cover移动止损")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False
            #         self.flag=False
            #         self.trailing_flag=False
            # if self.rate>0.09:
            #     if self.pos_==1:
            #         self.sell(bar.close_price - 5,self.fixed_size1)
            #         self.write_log("sell止盈")
            #         self.pos_=0
            #         self.can_enter_short=True
            #         self.can_enter_long=False
            #         self.flag=False
            #         self.trailing_flag=False
            #     if self.pos_==-1:
            #         self.cover(bar.close_price + 5,self.fixed_size1)
            #         self.write_log("cover止盈")
            #         self.pos_=0
            #         self.can_enter_long=True
            #         self.can_enter_short=False
            #         self.flag=False
            #         self.trailing_flag=False

        # atr_array = am.atr(self.atr_length, array=True)
        # self.atr_value = atr_array[-1]
        # self.atr_ma = atr_array[-self.atr_ma_length:].mean()
        # self.rsi_value = am.rsi(self.rsi_length)

        # if self.pos == 0:
        #     self.intra_trade_high = bar.high_price
        #     self.intra_trade_low = bar.low_price

        #     if self.atr_value > self.atr_ma:
        #         if self.rsi_value > self.rsi_buy:
        #             self.buy(bar.close_price + 5, self.fixed_size)
        #         elif self.rsi_value < self.rsi_sell:
        #             self.short(bar.close_price - 5, self.fixed_size)

        # elif self.pos > 0:
        #     self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
        #     self.intra_trade_low = bar.low_price

        #     long_stop = self.intra_trade_high * \
        #         (1 - self.trailing_percent / 100)
        #     self.sell(long_stop, abs(self.pos), stop=True)

        # elif self.pos < 0:
        #     self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
        #     self.intra_trade_high = bar.high_price

        #     short_stop = self.intra_trade_low * \
        #         (1 + self.trailing_percent / 100)
        #     self.cover(short_stop, abs(self.pos), stop=True)
        
        self.put_event()
        
    def on_5min(self):
        if self.am1.inited and self.flag:
            # print(self.am.close)
            atr_array = self.am1.atr(self.atr_length, array=True)
            # print(atr_array)
            self.atr_value = atr_array[-1]
            # self.atr_ma = atr_array[-self.atr_ma_length:].mean()
            self.trailing_point_sell=self.high_price-self.atr_value*self.gap_base
            self.trailing_point_cover=self.high_price+self.atr_value*self.gap_base
            self.trailing_flag=True
            # print(self.trailing_point,bar.close_price)
        
        # print(self.trailing_point,bar.close_price)
    def caculate_signal(self,df:DataFrame)->pd.Series:
        print("计算因子前")
        print(df.shape)
        df:pd.DataFrame=self.caculate_factor(df)
        # print(df)
        # df=df.drop(["open","high","low","volume"],axis=1)
        yvalid_list:List = []
        for m in self.model:
            yvalid_list.append(m.predict(df.values))
        yvalid:pd.Series=pd.Series(np.array([i for i in yvalid_list]).mean(axis=0),index=df.index)
        print("计算因子后")
        print(yvalid.shape)
        yvalid.fillna(method='pad',inplace=True)
        return yvalid
    """
    后面考虑清楚再修改
    """
    def caculate_signal_one_line(self,df:DataFrame)->float:
        df:pd.DataFrame=self.caculate_factor(df).iloc[-1]
        yvalid=0
        for m in self.model:
            yvalid+=m.predict(df)
        yvalid/=3
        return yvalid
    
    @staticmethod
    def caculate_factor(df:pd.DataFrame)->pd.DataFrame:
        factor_names=['120mom','1mom','2mom','5mom','60_hl_interval','60_hl_interval_V','60mom','EE120','EE20','EE60','HL_STD_1','HL_STD_1_60','HL_STD_2','MM_20_stab','RSRS_1','RSRS_1_60','RSRS_1_V_60','RSRS_2','RSRS_2_V_60','RSSRSS','RSSRSS_60','RSSRSS_V_20','RSSRSS_V_60','TS20_H','TS20_L','TS60_H','TS60_L','accu_money_1','accu_money_10','accu_money_1_VI','accu_money_1_VI_10','accu_money_1_VI_60','accu_money_60','alpha001','alpha0012','alpha0012_60','alpha001_60','alpha002','alpha002_60','alpha003','alpha003_60','alpha004','alpha004_60','c_ab_o','c_ab_o_v','close','close_kurt_rl_20D','close_kurt_rl_60D','close_max_rl_20D','close_max_rl_60D','close_mean_rl_20D','close_mean_rl_60D','close_min_rl_20D','close_min_rl_60D','close_skew_rl_20D','close_skew_rl_60D','close_var_rl_20D','close_var_rl_60D','csstd20_ab_csstd20','csstd20_ab_csstd20_v','m1_div_60','m5_div_60','m_ab_m20','mc_r20std','mc_r60std','money','open_b','open_b_BOOL','open_interest','time_min','time_min_9','v_i','vi1_div_60','vi5_div_60','volume_kurt_rl_20D','volume_kurt_rl_60D','volume_max_rl_20D','volume_max_rl_60D','volume_mean_rl_20D','volume_mean_rl_60D','volume_min_rl_20D','volume_min_rl_60D','volume_skew_rl_20D','volume_skew_rl_60D','volume_var_rl_20D','volume_var_rl_60D','y_1_gap','yes_H_pct','yes_H_pct_BOOL','yes_L_pct','yes_L_pct_BOOL']

        # print(len(factor_names))
        time_factor=create_time_factor(df.copy()).drop(["open","high","low","volume","open_interest","money","close"],axis=1)
        # print(time_factor)
        # print(time_factor.isnull().sum())
        df_factor=create_factor(df.copy())
        # print(df_factor)
        # print(df_factor)
        # print(df_factor.isnull().sum())
        
        # print(time_factor)
        print("df_factor---")
        print(df_factor)
        print("time_factor---")
        print(time_factor)
        df=pd.concat((time_factor,df_factor),axis=1).loc[:,factor_names]#.dropna()
        print("df-----")

        print(df)
        df=df.dropna(axis=0)
        print("df.dropna()")
        print(df)
        return df
    
    def on_30min_bar(self,bar:BarData):
        if self.am1.inited and self.flag:
            # print(self.am.close)
            atr_array = self.am1.atr(self.atr_length, array=True)
            # print(atr_array)
            self.atr_value = atr_array[-1]
            # self.atr_ma = atr_array[-self.atr_ma_length:].mean()
            self.trailing_point_sell=self.high_price-self.atr_value*self.gap_base
            self.trailing_point_cover=self.high_price+self.atr_value*self.gap_base
            self.trailing_flag=True
            # print(self.trailing_point,bar.close_price)
        
        # print(self.trailing_point,bar.close_price)
    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        # if order.offset==Offset.OPEN and order.vt_orderid!=self.comb_status.open_order_status.vt_orderid:
        #     return
        # if order.offset==Offset.CLOSE or order.offset==Offset.CLOSETODAY or order.offset==Offset.CLOSEYESTERDAY and order.vt_orderid!=self.comb_status.close_order_status.vt_orderid:
        #     return
        
        # if order.status==Status.NOTTRADED and order.orderid==self.order_status.orderid:#只记录open的各种volume，close的volume可以忽略
            # self.order_status.order_volume=order.volume#订单的实际数量
            # self.order_status.can_cancel_count=order.volume#订单的可撤数量
        # if order.status==Status.CANCELLED and order.vt_orderid in self.disconnect_order_list:
        #     self.write_log("因为有未成交委托，所以撤单")
        #     """
        #     但理论上根本不会推到策略里去的
        #     """
        #     return
        self.comb_status.on_order(order)
        if order.status==Status.CANCELLED:#只有开仓的订单，才有可能被撤
            # self.order_status.can_cancel_count=0#撤单d后的can_cancel数量肯定是0，
            # if self.order_status.traded_volume==0:#当开仓时增加traded_volume，在平仓时扣减traded_volume，语义上有一点问题，但是逻辑应该没问题
            # self.order_status.can_cancel_count=order.volume-order.traded#发单数量-成交数量，就是撤单的数量，也就是需要补单的数量
            """
            下面逻辑要修改，仅仅是收到撤单的不一定要开仓，必须是close的成交和撤单，都收到了，才发单，这里需要判断close是不是已经完成，成交的部分加上能撤单的部分是原始订单数量，先假定在平仓的时候，不会有新的开仓单成交
            """
            # self.comb_status.open_order_status.can_cancel_count=0
            if order.offset==Offset.OPEN:
                if self.signal==0:
                    self.can_enter_short=True
                    self.can_enter_long=True
                    self.write_log("我因为信号0撤单")
                    return 
                if not self.is_cancel_order_trade:
                    self.write_log("因为有未成交委托，所以撤单")
                    """
                    但理论上根本不会推到策略里去的
                    """
                    return
                # fix_size=self.fixed_size
                self.write_log("撤单完成")
                if self.comb_status.is_trade_after_cancel_order():
                    #开空撤单，意味着信号变换-1到1，需要开多了
                    if order.direction==Direction.SHORT:
                        
                        vt_orderid=self.buy(self.comb_status.open_price,self.comb_status.open_volume)[0]
                        self.write_log("限价单一直没成交，先撤单，再多")

                    #开多撤单，意味着信号由1到-1，需要开空了
                        self.write_log("buy")
                    if order.direction==Direction.LONG:
                        print(self.comb_status.open_price,self.comb_status.open_volume,"xxxxx")
                        vt_orderid=self.short(self.comb_status.open_price,self.comb_status.open_volume)[0]
                        self.write_log("限价单一直没成交，先撤单，再空")
                        self.write_log("short")
                    order_status=OrderStatus(vt_orderid=vt_orderid,price=self.comb_status.open_price)
                    self.comb_status=ComOrder(open_order_status=order_status)
                    self.write_log("我改变了ComOrder在Cancel里")
                # if order.status==Status.ALLTRADED and order.orderid == self.order_status.orderid and order.offset==Offset.OPEN:
                #     self.order_status.orderid=None    
                # if Status.PARTTRADED
                        # self.write_log(self.order_status.datetime)
                        # self.write_log(self.order_status.datetime.hour)
                    self.write_log(str(order))
                    return
            if (order.offset==Offset.CLOSE or order.offset==Offset.CLOSETODAY or order.offset==Offset.CLOSEYESTERDAY):
                pass    
        if (order.offset==Offset.CLOSE or order.offset==Offset.CLOSETODAY or order.offset==Offset.CLOSEYESTERDAY) and order.status==Status.ALLTRADED:
            # self.order_status.volume-=trade.volume
            if self.signal==0:
                self.write_log("我因为信号0，平仓")
                self.write_log(str(order))
                self.can_enter_long=True
                self.can_enter_short=True
                return
            self.write_log("我平仓完了")
            self.write_log("可以平仓的数量:{}".format(self.comb_status.can_cancel_count))
            self.write_log("close.order_volume:{},close.traded_volume:{}".format(self.comb_status.close_order_status.order_volume,self.comb_status.close_traded_volume))
            if self.comb_status.is_trade_after_close_order_all_traded():
                self.write_log("我不仅平仓完了，而且我进了发单逻辑")
                if order.direction==Direction.SHORT:
                    #sell 完就short
                    vt_orderid=self.short(self.comb_status.close_price,self.comb_status.close_volume)[0]
                    self.write_log("进入先卖再空")
                    self.write_log("short")
                if order.direction==Direction.LONG:
                    #cover 完就buy
                    vt_orderid=self.buy(self.comb_status.close_price,self.comb_status.close_volume)[0]
                    self.write_log("进入先平仓再多")
                    self.write_log("buy")
                open_order_status=OrderStatus(vt_orderid=vt_orderid,price=self.comb_status)        
                self.comb_status=ComOrder(open_order_status=open_order_status)
                self.write_log("我改变了ComOrder，在ALLTRADED里")
            # self.write_log(str(order))
            # self.write_log(order)
            # self.write_log(self.positions)
            # self.write_log(("在order里 self.order_status",self.comb_status.open_order_status))
            # pass
        ###对挂的限价单，处理较少，需要仔细思考清楚
        self.write_log(str(order))

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        
        self.write_log(str(trade))

        # self.comb_status.(trade)
        # print(trade)
        self.price_complete=trade.price
        self.start_time=trade.datetime
        
            
        
        try:
            if trade.offset==Offset.OPEN:
                
                self.write_log("我进来了")
                if trade.direction==Direction.LONG:
                    send_wechat(str(trade.symbol)+"开多单，"+"数量是:{}，价格是:{}，成交时间:{}".format(trade.volume,trade.price,trade.datetime))
                    self.position_=1

                if trade.direction==Direction.SHORT:
                    send_wechat(str(trade.symbol)+"开空单，"+"数量是:{}，价格是:{}，成交时间:{}".format(trade.volume,trade.price,trade.datetime))
                    self.position_=-1
            if trade.offset==Offset.CLOSE or trade.offset==Offset.CLOSETODAY or trade.offset==Offset.CLOSEYESTERDAY:
                if trade.direction==Direction.LONG:
                    send_wechat(str(trade.symbol)+"平空单，"+"数量是:{}，价格是:{}，成交时间:{}".format(trade.volume,trade.price,trade.datetime))
                if trade.direction==Direction.SHORT:
                    send_wechat(str(trade.symbol)+"平多单，"+"数量是:{}，价格是:{}，成交时间:{}".format(trade.volume,trade.price,trade.datetime))
        except Exception as e:
            self.write_log("处在一个非常傻逼的错误位置"+str(e))
        if trade.direction==Direction.LONG:
            self.position+=trade.volume
            
            print("多",self.position,trade.volume)
            # if self.position!=0 and self.position!=trade.volume and self.position!=-trade.volume:
            #     raise ValueError("laji!!")
        if trade.direction==Direction.SHORT:
            self.position-=trade.volume
            
            print("空",self.position,trade.volume)
            # if self.position!=0 and self.position!=trade.volume and self.position!=-trade.volume:
            #     raise ValueError("laji!!")
        self.flag=True
        self.high_price = trade.price 
        # self.write_log("在trade里，self.order_status"+str(self.comb_status.open_orderid))
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        self.write_log(str(stop_order))
        pass
